﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Threading;

using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.VideoSurveillance;

namespace VideoSurveilance
{
    public class JPEG_IPCamera : IPCamera
    {

        private CameraEventHandler newFrame;
        private string m_strurlsrc;
        
        private Capture _cameraCapture;
        private Thread m_localthrd;

        private Image<Bgr, Byte> frame;

        private bool m_running = true;

        public JPEG_IPCamera()
        {
            m_strurlsrc = null;
            newFrame = null;
            m_localthrd = new Thread(new ThreadStart(DoLoadingImg));
        }

        public override CameraEventHandler NewFrame
        {
            get { return newFrame; }
            set
            {
                newFrame = value;
            }
        }

        public override void Dispose()
        {
            m_running = false;
            m_localthrd.Join();
        }

        public override string URLSRC
        {
            get { return m_strurlsrc;}
            set
            {
                if (value != null && m_strurlsrc == null)
                {
                    m_strurlsrc = value;
                    m_localthrd.Start();
                }
            }
        }

        private void DoLoadingImg()
        {
            while (m_running)
            {
                if (m_strurlsrc == null)
                {
                    continue;
                }

                try
                {
                    _cameraCapture = new Capture(m_strurlsrc);
                }
                catch (Exception e)
                {
                    Thread.Sleep(2500);
                    continue;
                }

                _cameraCapture.Start();

                Image<Bgr, Byte> frame1 = _cameraCapture.RetrieveBgrFrame();

                while (frame1 == null)
                {
                    frame1 = _cameraCapture.RetrieveBgrFrame();
                }

                if (frame != null)
                {
                    frame.Dispose();
                }
                frame = frame1.Clone();

                if (newFrame != null)
                {
                    CameraEventArgs arg = new CameraEventArgs(frame);
                    newFrame(this, arg);
                }
                
                _cameraCapture.Stop();

                // Claim resource of inner thread
                _cameraCapture.Wait();
                
            }
        }        
    }
}
